"""
计算最后一个周五的日期

问题：
    你需要查找星期中某一天最后出现的日期，比如星期五。
解决方案：
    Python的 datetime 模块中有工具函数和类可以帮助你执行这样的计算。
"""

from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from dateutil.rrule import FR

weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]


def get_previous_by_day(day_name, start_date=None):
    """
    原理：
        先将开始日期和目标日期映射到星期数组的位置上(星期一索引为0)，
        然后通过模运算计算出目标日期要经过多少天才能到达开始日期。
        然后用开始日期减去那个时间差即得到结果日期。
    """

    if start_date is None:
        start_date = datetime.today()

    day_num = start_date.weekday()
    day_num_target = weekdays.index(day_name)
    days_ago = (7 + day_num - day_num_target) % 7
    if days_ago == 0:
        days_ago = 7

    target_date = start_date - timedelta(days=days_ago)
    return target_date


def use_day():
    print(get_previous_by_day("Friday", datetime(2018, 5, 28)))
    # 输出结果：
    """
    2018-05-25 00:00:00
    """


def use_dateutil():
    now = datetime.now()
    print(now)
    # 下一星期五
    print(now + relativedelta(weekday=FR))
    # 上一个星期五
    print(now + relativedelta(weekday=FR(-1)))
    # 输出结果：
    """
    2018-05-28 22:36:25.974507
    2018-06-01 22:36:25.974507
    2018-05-25 22:36:25.974507
    """


if __name__ == '__main__':
    use_day()
    use_dateutil()
